package IceAssembly;

/**
 *  <html>
 *    <head>
 *     
 *    </head>
 *    <body>
 *      <p style="margin-top: 0">
 *        Will take the whole line string and break it into labels, Mnemonics,
 *        functions, parameters. index0 of the returned string array is reserved
 *        to identify if the returned string array has a label or not. If the
 *        index0 is 0 means no label in the returned string array and if it is 1
 *        means a label in the returned string array.
 *      </p>
 *    </body>
 *  </html>
 */
public class Tokenize implements Interface {
    Table table_instance = new Table();
    public static void main(String []args){
        Tokenize t=new Tokenize();
        String [] s=t.tokenize( " label moper add,0");
        for (int i=0;i<s.length;i++)
            System.out.println(s[i]+":");
    }
    /**
    * The numOfSpaces function will look at each character in the string and count the number of spaces found.  The number of spaces that are encountered is then returned.
    * <p>
    * <b>Change Log:</b><br>
    * 4/16/08 - Initial Code Entry - Aashish <br>
     * 4/26/08 - Entered documentation - Keith Hill<br>
    * <p>
    * <b>Error Messages Generated:</b><br>
    * <INSERT EACH ERROR MESSAGE GENERATED> <br>
    * <p>
    * <b>Date of module being installed:</b> 4/16/08
    * @author Aashish
    * @param linestring This is the string that will be analyzed.
    * @return The number of spaces encountered in the string is returned.
    */
    private int numOfSpaces (String linestring)  {
        int count=0;
            for (int index=0;index<linestring.length();index++){
               if(linestring.charAt(index)==' ')
                   count++;
            }
        return count;
    }
    
    /**
    * The indexOfNthSpaceOccurrence function will receive a string and an integer.  The integer provided is the number of space that 
     * the caller is interested and the function will return the location of that space.  For example, if there are 5 spaces in a string and the 
     * caller wants to know the indexed location of the 3rd space, this function will produce it.
    * <p>
    * <b>Change Log:</b><br>
    * 4/16/08 - Initial Code Entry - Aashish<br>
     * 4/26/08 - Documentation Entered - Keith Hill <br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <INSERT EACH CONDITION TESTED> <br>
    * <p>
    * <b>Date of module being installed:</b> 4/16/08
    * @author Aashish
    * @param linestring This is the line that is to be analyzed.
    * @param occurrence This is the the desired number of occurrence specified by the caller.
    * @return The function will return the location of that space.
*/
    private int indexOfNthSpaceOccurrence(String linestring,int occurrence ){
        int count=0;
            for (int index=0;index<linestring.length();index++){
               if(linestring.charAt(index)==' '){
                   count++;
                   if (count==occurrence)
                       return index;
               }
            }
        return count;
   
    }
    
    /**
    * The numOfCommas function will look at each character in the string and count the number of commas found.  The number of commas that are encountered is then returned.
    * <p>
    * <b>Change Log:</b><br>
    * 4/16/08 - Initial Code Entry - Aashish <br>
     * 4/26/08 - Entered documentation - Keith Hill<br>
    * <p>
    * <b>Error Messages Generated:</b><br>
    * <INSERT EACH ERROR MESSAGE GENERATED> <br>
    * <p>
    * <b>Date of module being installed:</b> 4/16/08
    * @author Aashish
    * @param linestring This is the string that will be analyzed.
    * @return The number of commas encountered in the string is returned.
    */
    private int numOfCommas(String linestring)  {
        int count=0;
            for (int index=0;index<linestring.length();index++){
               if(linestring.charAt(index)==',')
                   count++;
            }
        return count;
    }
     
    /**
    * The handleWithNoCommaLinestring function is called if a comma is not located in the line and needs to be tokenized.
    * <p>
    * <b>Change Log:</b><br>
    * 4/16/08 - Initial Code Entry - Aashish <br>
     * 4/26/08 - Entered documentation - Keith Hill<br>
    * <p>
    * <b>Error Messages Generated:</b><br>
    * <br>
    * <p>
    * <b>Date of module being installed:</b> 4/16/08
    * @author Aashish
    * @param linestring This is the string that will be analyzed.
    * @return The function will return a string array that includes a code, label, directive/operation, function, seperator character, and operand.
    */    
    private String[] handleNoCommaLinestring(String linestring){
        String [] broken_string=new String [6];
        if (linestring.charAt(0)!= ' '){//Case with a label...
                broken_string[0]="1";
                switch(numOfSpaces(linestring)){
                    case 0: broken_string[1]=linestring;
                            broken_string[2]="";
                            broken_string[3]="";
                            broken_string[4]="";
                            broken_string[5]="";
                            break;
                    case 1: int index_of_space = linestring.indexOf(" ",0);
                            broken_string[1]=linestring.substring(0,index_of_space);
                            broken_string[2]=linestring.substring(index_of_space+1,linestring.length());
                            broken_string[3]="";
                            broken_string[4]="";
                            broken_string[5]="";
                            break;
                    default:int index_of_space_1 = indexOfNthSpaceOccurrence(linestring, 1);
                            int index_of_space_2 = indexOfNthSpaceOccurrence(linestring, 2);
                            broken_string[1]=linestring.substring(0,index_of_space_1);
                            broken_string[2]=linestring.substring(index_of_space_1+1,index_of_space_2);
                            broken_string[3]=linestring.substring(index_of_space_2+1,linestring.length());                                                          
                            broken_string[4]="";
                            broken_string[5]="";
                  }                         
            }
            else{ //case without a label...
                broken_string[0]="0";
                switch(numOfSpaces(linestring)){
                    case 1: broken_string[2]=linestring.substring(1);
                            break;
                    default:int index_of_space_2 = indexOfNthSpaceOccurrence(linestring,2);
                            broken_string[2]=linestring.substring(1,index_of_space_2);
                            broken_string[3]=linestring.substring(index_of_space_2+1,linestring.length());
                            broken_string[4]="";
                            broken_string[5]="";
                }                                         
            }
        return broken_string;
    }
    /**
    * The handleWithCommaLinestring function is called if a comma is located in the line and needs to be tokenized.
    * <p>
    * <b>Change Log:</b><br>
    * 4/16/08 - Initial Code Entry - Aashish <br>
     * 4/26/08 - Entered documentation - Keith Hill<br>
    * <p>
    * <b>Error Messages Generated:</b><br>
    * 110 - There are multiple commas in the string. <br>
    * <p>
    * <b>Date of module being installed:</b> 4/16/08
    * @author Aashish
    * @param linestring This is the string that will be analyzed.
    * @return The function will return a string array that includes a code, label, directive/operation, function, seperator character, and operand.
    */
    private String[] handleWithCommaLinestring(String linestring){
        String [] broken_string=new String [6];
        int no_of_commas=numOfCommas(linestring);
        int index_of_comma=linestring.indexOf(",");
        if (no_of_commas>1){
            //initialize the broken string with moper add,=0 and return and throw an error...
            table_instance.addToErrorTable("110");
            broken_string[0]="0";
            broken_string[1]="";
            broken_string[2]="Moper";
            broken_string[3]="add";
            broken_string[4]=",";
            broken_string[5]="=0";
            return broken_string;
        }
        else{//means just one comma only always...           
            if(linestring.contains(" ,")){
                linestring = linestring.replaceFirst(" ," , ",");
                //and throw an error
            }
            if(linestring.contains(", ")){
                linestring = linestring.replaceFirst(", " , ",");
                //and throw an error
            }           
            index_of_comma=linestring.indexOf(",");//some changes may have occur due to above code...
            String directive_similar_part = linestring.substring(0, index_of_comma);            
            String operand;
            try{
                operand = linestring.substring(index_of_comma+1,linestring.length());
            }catch(ArrayIndexOutOfBoundsException e){
                operand = "";
            }
            String[] no_operand_tokened_string = handleNoCommaLinestring(directive_similar_part);
            for(int index=0; index<4; index++){
                broken_string[index] = no_operand_tokened_string[index];
            }
            broken_string[4]=",";
            broken_string[5]=operand;
           
        }
      return broken_string;
    }
    
        /**
    * The Tokenize function is used to tokenize a given string.  It will call appropriate helper functions and then return a string array with necessary pieces.
    * <p>
    * <b>Change Log:</b><br>
    * 4/16/08 - Initial Code Entry - Aashish <br>
     * 4/26/08 - Entered documentation - Keith Hill<br>
    * <p>
    * <b>Error Messages Generated:</b><br>
    * <br>
    * <p>
    * <b>Date of module being installed:</b> 4/16/08
    * @author Aashish
    * @param linestring This is the string that will be analyzed.
    * @return The function will return a string array that includes a code, label, directive/operation, function, seperator character, and operand.
    */
    public String[] tokenize (String linestring) {       
        if (linestring.indexOf(",",0)!=-1){  
            return(handleWithCommaLinestring(linestring));
        }     
        else{//No Comma in the linestring...
            return(handleNoCommaLinestring(linestring));   
        }       
    } 
}